#include "TTI.h"
#include <string>

using namespace TTP;
using namespace std;

class ChatState : public TTP::State {

   string name;
   uint32_t last_hist;

   void addMessage(uint32_t t, const string& msg) {
      cout << "(" << t << ") " << name << ": " << msg << endl;
   }

   void changeName(const string& s) {
      name = s;
   }

public:
   ChatState() : last_hist(0) {
      Register(this, &ChatState::addMessage);
      Register(this, &ChatState::changeName);
   }

   void say(const string& s) {
      uint32_t t = time(0);
      cout << "(" << t << ") " << name << ": " << s << endl;
      call_remote(&ChatState::addMessage, t, s);
   }

   void setName(const string& s) {
      name = s;
      call_remote(&ChatState::changeName, s);
   }
};

ChatState * myState;

State * makeState() { return new ChatState(); }
State * cloneState(const State& s) {
   const ChatState *cs = dynamic_cast<const ChatState*>(&s);
   if(cs == NULL) throw msg_exception("OMGWTFBBQ");
   else return new ChatState(*cs); 
}

int main () {
   myState = new ChatState();
   TTI &tti = *TTI::get();
   tti.regStateFactory(makeState);
   tti.regStateCloner(cloneState);

   tti.regState(myState);

   tti.initialize();

   string s;

   for(;;) {
      getline(cin, s); 
      myState->say(s);
   }
}
